package com.atguigu.teach.mytask;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class AirCondition{
    int number=0;
    Lock lock=new ReentrantLock();
    Condition condition=lock.newCondition();
    public synchronized  void increment() throws InterruptedException {
        //1判断
        while(number!=0){
           this.wait();
        }
        //2干活
        System.out.println(Thread.currentThread().getName()+"\t"+(++number));
        //3通知
        this.notifyAll();
    }
    public   void increment2() throws InterruptedException {
       lock.lock();
          try{
              //1判断
          while(number!=0){
              condition.await();
          }
            //2干活
              System.out.println(Thread.currentThread().getName()+"\t"+(++number));
            //3通知
              condition.signalAll();
          }catch (Exception e){

          }finally {
              lock.unlock();
          }
    }

    public synchronized  void decrement() throws InterruptedException {
        //1判断
        while(number==0){
            this.wait();
        }
        //2干活
        System.out.println(Thread.currentThread().getName()+"\t"+(--number));
        //3通知
        this.notifyAll();

    }
    public   void decrement2() throws InterruptedException {
                lock.lock();
                try{
                    //1判断
                    while(number==0){
                      condition.await();
                    }
                    //2干活
                    System.out.println(Thread.currentThread().getName()+"\t"+(--number));
                    //3通知
                  condition.signalAll();
                }catch (Exception e){

                }finally {
                    lock.unlock();
                }


    }
}
/**
 * @deprecated:生产消费者
 *@description: 有一个初始值为零的变量，现有两个线程对该变量操作
 *               实现一个线程对变量+1,实现一个线程对变量减1，交替执行10次
 *               1高内聚低耦合的前提下，线程 操作 资源类
 *               2判断，干活，通知
 *               3需要注意虚假唤醒，多线程交互判断在使用wait方法的时候，判断不可以用if，要用while
 *
 * @return:
 * @exception/throws: 
 * @author: zxb
 * @date:   2021/10/20
 */

public class MyProdConsumerDemo {
    public static void main(String[] args) {
        AirCondition airCondition = new AirCondition();
        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    airCondition.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        },"A").start();
        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    airCondition.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        },"C").start();
        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    airCondition.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        },"D").start();
        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    airCondition.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        },"B").start();


        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    airCondition.increment2();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        },"A").start();

        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    airCondition.decrement2();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        },"B").start();

        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    airCondition.decrement2();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        },"C").start();

        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                try {
                    airCondition.increment2();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        },"D").start();

    }
}
